import Event from "da-event"
import environment from "@/environment"
import { retryWhen, delay, take, interval, tap, filter, switchMap, timeout, catchError, of, map, defer } from "rxjs"
import { webSocket } from 'rxjs/webSocket';
import { message as antdMessage } from "antd"

export class WssService extends Event {
  socket$ = null
  ping_subscription = null
  socket_subscription = null
  destroyed = false
  connection_status = "disconnected"
  startPingInterval(message) {
    if (message.type === "open") {
      this.connection_status = "connected";
      this.ping_subscription = interval(10000).pipe(
        tap(() => {
          if (this.connection_status !== "connected") return
          console.log('发送 ping 消息...1');
          this.send({type: "ping"});  // 发送 ping 消息
        })
      ).subscribe();
    }
    return message
  }
  bootstrap() {
    const socket$ = webSocket(environment.wssUrl);
    this.socket$ = socket$;
    this.socket_subscription = socket$.pipe(
      retryWhen(errors =>
        errors.pipe(
          delay(2000),  // 延迟 2 秒重试
          // take(5)   // 尝试重连 5 次
        )
      ),
      map(msg => this.startPingInterval(msg)),
      filter(msg => !["open", "pong"].includes(msg.type))
    ).subscribe({
      next: (msg) => this.handleMessage(msg),
      error: (err) => console.error('错误:', err),
      complete: () => {
        this.connection_status = "disconnected";
        if (this.ping_subscription) {
          this.ping_subscription.unsubscribe();
        }
        console.log('WebSocket 连接关闭')
      }
    });
  }
  handleMessage(msg) {
    this.emit(msg.type, msg)
  }
  send(msg) {
    console.error("发送消息:", JSON.stringify(msg));
    // return
    if (this.connection_status === "disconnected") {
      antdMessage.error("WebSocket 未连接")
      return
    }

    this.socket$.next(msg)
  }
  startBaku() {
    this.send({type: "start_baku"})
  }
  startPetBattle() {
    this.send({type: "start_key_press_list", extra_data: {
      key_list: [
        {key: '8', interval: 1.5},
        {key: '9', interval: 1.5},
      ]
    }})
  }
  startAutoClickTargetImage(payload) {
    this.send({type: "start_auto_click_target_image", extra_data: {...payload}})
  }
  startCraftGroup(payload) {
    this.send({type: "start_craft_group", extra_data: {...payload}})
  }
  startAutoCraft(payload) {
    this.send({type: "start_auto_craft", extra_data: {...payload}})
  }
  startAutoOrder(payload) {
    this.send({type: "start_auto_order", extra_data: {...payload}})
  }
  startSalvageCard(payload) {
    this.send({type: "start_auto_salvage_card", extra_data: {...payload}})
  }

  startKeyPressList(payload) {
    this.send({type: "start_key_press_list", extra_data: {...payload}})
  }

  startPressNum1() {
    this.send({type: "start_key_press_list", extra_data: {
      key_list: [
        {key: '1', interval: 1},
      ]
    }})
  }

  startMouseClick(payload) {
    this.send({type: "start_mouse_click", extra_data: {...payload}})
  }

  startDebug() {
    this.send({type: "debug"})
  }

  resetWowClient() {
    this.send({type: "reset_wow_exe", extra_data: {account: "wow1"}})
  }

  startRecord(payload) {
    this.send({type: "start_record_actions", extra_data: {...payload}})
  }

  stopRecord() {
    this.send({type: "stop_record_actions", extra_data: {filename: "abc"}})
  }

  playRecord() {
    this.send({type: "play_record_actions", extra_data: {record_events_file: "abs_1753415202.json"}})
  }

  stopPlayRecord() {
    this.send({type: "stop_play_record_actions", extra_data: {filename: "abc"}})
  }

  hotRefreshSchedule(ids) {
    this.send({type: "hot_refresh_schedule", extra_data: {ids}})
  }

  toggleScheduleLocked(locked) {
    this.send({type: "toggle_schedule_locked", extra_data: {locked}})
  }
  
  stopAllTask() {
    this.send({type: "stop_all_task"})
  }
  destroy() {
    this.destroyed = true;
    if (this.ping_subscription) {
      this.ping_subscription.unsubscribe();
    }
    if (this.socket_subscription) {
      this.socket_subscription.unsubscribe();  // 取消订阅
    }
    if (this.socket$) {
      this.socket$.complete();  // 关闭 WebSocket 连接
    }
    this.connection_status = "disconnected";
  }
}


const $wss = new WssService();
export default $wss;